#include "poller.h"
#include "fd_guard.h"
#include <utility>
#include <cstring>
#include <cerrno>
#include <stdexcept>
#include <system_error>
#include "../util/logger.h"

using namespace ::std::chrono_literals;

namespace wilson::sys
{
    poller::poller()
        : p_epfd{ ::epoll_create(5000) }
    {
    }

    void poller::add(sys::borrowed_fd fd, uint32_t event)
    {
        epoll_event epev{};
        epev.events = event | EPOLLET | EPOLLONESHOT;
        epev.data.fd = fd;

        if (int ret = ::epoll_ctl(p_epfd, EPOLL_CTL_ADD, fd, &epev);
            ret == -1) [[unlikely]]
        {
            throw ::std::runtime_error{ ::strerror(errno) };
        }
    }

    void poller::mod(sys::borrowed_fd fd, uint32_t event)
    {
        epoll_event epev{};
        epev.events = event | EPOLLET | EPOLLONESHOT;
        epev.data.fd = fd;

        if (int ret = ::epoll_ctl(p_epfd, EPOLL_CTL_MOD, fd, &epev);
            ret == -1) [[unlikely]]
        {
            throw ::std::runtime_error{ ::strerror(errno) };
        }
    }

    void poller::del(sys::borrowed_fd fd)
    {
        if (int ret = ::epoll_ctl(p_epfd, EPOLL_CTL_DEL, fd, nullptr);
            ret == -1) [[unlikely]]
        {
            int errval = errno;
            WILSON_LOG_DEBUG(fmt::format("errval: {}, msg {}\n", 
                errval, ::strerror(errval))
            );
            throw ::std::runtime_error{ ::strerror(errno) };
        }
    }
}
